/*******************************************************************************
 *  Element class
 ******************************************************************************/

var Element = function(element) {
    
    this[0] = element;
    
    /*
     *  Can be overridden if it is need
     */
    this.defaults = {};
    
    /*
     *  Defines element settings
     */
    this.settings = {};
    
    /* 
     *  Merges defaults and options, without modifying defaults
     *  @param options defines options for mixing
     */
    this.prepareSettings = function(options){
        this.getElement()[0].wrapper = this;
        return this.settings = $.extend(true, {}, this.defaults, options);
    }
    
    /**
     *  Sets element to wrap
     *  @return class instance
     */
    this.setElement = function(element){
        this[0] = element;
        return this;
    };
    
    /**
     *  Sets text
     *  @param text defines text
     *  @return class instance
     */
    this.setText = function(text){
        this.getElement().text(text);
        return this;
    };
    
    /**
     *  Sets id
     *  @param id defines id
     *  @return class instance
     */
    this.setId = function(id){
        return this.addAttribute('id', id);
    };
    
    /**
     *  Adds class
     *  @param classes defines one or more classes
     *  @return class instance
     */
    this.addClass = function(classes){
        if(classes!=null) this.getElement().addClass(classes);
        return this;
    };
    
    /**
     *  Removes class
     *  @param classes defines one or more classes
     *  @return class instance
     */
    this.removeClass = function(classes){
        if(classes!=null) this.getElement().removeClass(classes);
        return this;
    };
    
    /**
     *  Adds attribute
     *  @param attr defines attibute name
     *  @param value defines attibute value
     *  @return class instance
     */
    this.addAttribute = function(attr, value){
        if(value!=null && attr!=null) this.getElement().attr(attr, value);
        return this;
    };
    
    /**
     *  Disables element
     *  @return class instance
     */
    this.disable = function(){
        return this.setEnabled(false);
    }
    
    /**
     *  Enables element
     *  @return class instance
     */
    this.enable = function(){
        return this.setEnabled(true);
    }
    
    /**
     *  Sets enabled state
     *  @param isEnabled defines enabled state
     *  @return class instance
     */
    this.setEnabled = function(isEnabled){
        var $element = this.getElement();
        if(isEnabled){
            $element.removeAttr("disabled");
        } else {
            $element.attr("disabled","disabled")
        }
        return this;
    }
    
    this.isDisabled = function(){
        return this.getElement().is(':disabled') || this.getElement().is('.disabled');
    }
    
    /**
     *  Set one CSS propertie for the element
     *  @param propertyName defines property name
     *  @param value defines style value
     *  @return class instance
     */
    this.css = function(propertyName, value){
        this.getElement().css(propertyName, value);
        return this;
    };
    
    /**
     *  Returns element
     *  @return element
     */
    this.getElement = function(){
        return this[0];
    };
    
    /**
     *  Returns id
     *  @return id
     */
    this.getId = function(){
        return this.getElement().attr('id');
    };
    
    /**
     *  Appends element before the end of current element
     *  @param element defines element for append
     *  @return class instance
     */
    this.append = function(element){
        this.getElement().append(element.getElement())
        return this;
    }
}